package com.longcai.cm.auth;

import com.longcai.cm.common.constant.RedisPrefix;
import com.longcai.cm.domain.FaMember;
import com.longcai.cm.exception.SysRuntimeException;
import com.longcai.cm.service.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 有@LoginUser注解的方法参数，注入当前登录用户
 *
 * @author chenshun
 * @date 2017-03-23 22:02
 */
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    private final RedisService redisService;

    public LoginUserHandlerMethodArgumentResolver(RedisService redisService) {
        this.redisService = redisService;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return (parameter.getParameterType().isAssignableFrom(FaMember.class))
                && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public FaMember resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request,
                                    WebDataBinderFactory factory) {
        // 获取用户ID
        Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
        String requestToken = (String) request.getAttribute(AuthorizationInterceptor.TOKEN, RequestAttributes.SCOPE_REQUEST);
        if (object == null) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        String userId = String.valueOf(object);
        FaMember userInfo = redisService.get(RedisPrefix.LOGIN_USER + userId, FaMember.class);
        String currentToken = redisService.getToken(userId);
        if (userInfo == null) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        if (StringUtils.isEmpty(requestToken)) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        if (StringUtils.isEmpty(currentToken)) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        if (!currentToken.contains(requestToken)) {
            throw new SysRuntimeException("您的账号已经在别处登录", HttpStatus.UNAUTHORIZED.value());
        }
        // 获取用户信息
        return userInfo;
    }
}
